package com.eastfair.notice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.notice.dao.CommentMapper;
import com.eastfair.notice.entity.Comment;
import com.eastfair.notice.service.CommentService;
import com.eastfair.notice.vo.CommentVO;
import com.eastfair.projectcore.api.ProjectCoreServiceFeign;
import com.eastfair.core.snowflake.DefaultUidGenerator;
import com.eastfair.util.CodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 业务实现类
 * 评论回复表
 * </p>
 *
 * @author liuxiaobai
 * @date 2021-08-13
 */
@Slf4j
@Service
public class CommentServiceImpl extends SuperServiceImpl<CommentMapper, Comment> implements CommentService {

    @Autowired
    ProjectCoreServiceFeign projectCoreServiceFeign;

    /**************sharding 分库分表操作 *****************/
    @Override
    public boolean updateByIdOfShard(Comment entity) {
        UpdateWrapper<Comment> updateWrapper = new UpdateWrapper<>();
        //可将指定字段更新为null
        updateWrapper.lambda().eq(Comment::getProjectId, ContextUtil.getProjectId()).eq(Comment::getId, entity.getId());
        entity.setProjectId(null);
        //删除缓存
        return SqlHelper.retBool(this.getBaseMapper().update(entity, updateWrapper));
    }

    @Override
    protected R<Boolean> handlerSave(Comment model) {
        //雪花ID
        model.setId(DefaultUidGenerator.getUidOfProjectId(model.getProjectId()));
        return R.successDef();
    }

    /**
     * 保存回复
     *
     * @param comment 传入实体
     * @return 成功true/失败false
     */
    @Override
    public void saveComment(Comment comment) {
        //set层级code
        comment.setCode(initCode(comment.getParentId()));
        save(comment);
    }

    @Override
    public void assembleComment(List<CommentVO> commentVOList) {
        if (commentVOList.isEmpty()) {
            return;
        }
        //TODO 还需包装评论双方用户ID、姓名
        Set<Long> userIds = new HashSet<>();
        commentVOList.parallelStream().forEach(commentVO -> {
            userIds.add(commentVO.getUserId());
            userIds.add(commentVO.getParentUserId());
        });
    }

    /**
     * 根据parentId获取层级code
     *
     * @param parentId 父节点ID
     * @return parentId为null时返回一级code，不为null时获取parent层级拼接后返回子节点code
     */
    private String initCode(Long parentId) {
        String code = getCode();
        if (parentId == null) {
            //父节点为null 直接返回一级code
            return code;
        }
        Comment comment = getById(parentId);
        if (comment == null) {
            //根据parentId未查到父节点 直接返回一级code
            return code;
        }
        return comment.getCode() + "," + code;
    }

    /**
     * 获取一级code
     *
     * @return code
     */
    private String getCode() {
        String code = CodeUtils.randomCode(6);
        if (checkCodeExist(code)) {
            //库中code已存在 重新获取
            return getCode();
        }
        return code;
    }

    /**
     * 校验code是否已存在
     *
     * @param code 层级code
     * @return 已存在-true 不存在-false
     */
    private boolean checkCodeExist(String code) {
        QueryWrapper<Comment> query = new QueryWrapper<>();
        query.lambda()
                .eq(Comment::getProjectId, ContextUtil.getProjectId())
                .eq(Comment::getCode, code)
                .eq(Comment::getIsDelete, BusinessConstant.DELETE_NO);
        return count(query) > 0;
    }
}
